#pragma once

class Graphic_Particle_PolicyTemplate
{
protected:
	float mfInterval;
public:
	inline virtual void Begin(const float & Interval) throw(){ mfInterval = Interval; }
	inline virtual void operator()(Graphic_Particle & Target) = 0;
};

class Graphic_Particle_Policy_DoNothing
{
public:
	inline virtual void Begin(const float & Interval) throw(){ Interval; }
	inline virtual void operator()(Graphic_Particle & Target){}
};


class Graphic_Particle_PolicyStd_Position : public Graphic_Particle_PolicyTemplate
{
public:
	inline virtual void operator()(Graphic_Particle & Target)
	{
		Target.mPosition += Target.mVelocity * mfInterval;
	}
};

class Graphic_Particle_PolicyStd_Life : public Graphic_Particle_PolicyTemplate
{
public:
	inline virtual void operator()(Graphic_Particle & Target)
	{
		Target.mLife += Target.mLifeDelta * mfInterval;
	}
};

class Graphic_Particle_PolicyStd_Color
{
public:
	inline virtual void Begin(const float & Interval) throw(){ Interval; }
	inline virtual void operator()(Graphic_Particle & Target)
	{
		Target.mColor += ARGB(Target.mLife, 255, 255, 255);
	}
};


template <	class Policy_Velocity,	class Policy_Life, class Policy_Position,
			class Policy_Color,		class Policy_Size	>
class Graphic_Particle_StandardPolicy
{
protected:
	Policy_Velocity m_policy_Velocity;
	Policy_Life		m_policy_Life;
	Policy_Position m_policy_Position;
	Policy_Color	m_policy_Color;
	Policy_Size		m_policy_Size;
public:
	inline virtual void Begin(const float & Interval) throw()
	{
		m_policy_Velocity.Begin(Interval);
		m_policy_Life.Begin(Interval);
		m_policy_Position.Begin(Interval);
		m_policy_Color.Begin(Interval);
		m_policy_Size.Begin(Interval);
	}
	inline virtual void operator()(Graphic_Particle & Target) const throw()
	{
		m_policy_Velocity(Target);
		m_policy_Life(Target);
		m_policy_Position(Target);
		m_policy_Color(Target);
		m_policy_Size(Target);
	}
};